import { recordRTSPStream, snapshotRTSPStream, startRTSPStream, stopRTSPStream } from "@/apis/web/Camera"
import { useCrypto } from "@/hooks/useCrypto"
import { useLocalStorage } from "@/hooks/useLocalStorage"
import { RootState } from "@/store"
import { ICamera } from "@/store/models/Admin/CameraManagement/types"
import { ElMessage, ElNotification } from "element-plus"
import { Module } from "vuex"
import { IStreamControlActions, IStreamControlGetter, IStreamControlMutations, IStreamControlState } from "./types"
const state: IStreamControlState = {
    header: '视频流控制',
    dialog: {
        visible: false,
        title: '',
        confirm: {
            text: '确认',
            type: 'primary',
        },
        cancel: {
            text: '取消',
            type: 'default',
        },
    },
    recordBtn: {
        text: '录制',
        type: 'primary',
    },
    recordDialog: {
        slider: {
            label: '录制时长',
            labelWidth: '100px',
            min: 1,
            max: 300,
            duration: 1,
            formatter: (value: number) => `${value}秒`,
        },
        typeOpts: [
            { label: 'mp4', value: 'mp4' },
            // { label: 'avi', value: 'avi' },
        ]
    },
    snapshotBtn: {
        text: '截图',
        type: 'primary',
    },
    snapshotDialog: {
        typeOpts: [
            { label: 'jpg', value: 'jpg' },
            { label: 'png', value: 'png' },
            { label: 'bmp', value: 'bmp' },
        ]
    },
    common: {
        name: {
            label: '文件名称',
            labelWidth: '100px',
            placeholder: '请输入文件名称',
        },
        path: {
            label: '文件路径',
            labelWidth: '100px',
            placeholder: '请输入文件路径',
        },
        type: {
            label: '文件类型',
            labelWidth: '100px',
            placeholder: '请输入文件类型',
        },
    },
    form: {
        name: '',
        path: '',
        type: '',
    },
    streamState: new Map(),
}

const actions: IStreamControlActions = {
    onConfirm({ commit, rootState }, { name, camera }) {
        commit('_onConfirm', { name, user: rootState.user.user._id, camera: camera._id })
        commit('_onInitForm')
    },
    onCancel({ commit, rootState }) {
        commit('_onCancel')
        commit('_onInitForm')
    }
}

const mutations: IStreamControlMutations = {
    _initStreamState: (state: IStreamControlState, cameras: ICamera[]) => {
        cameras.forEach((c: ICamera) => state.streamState.set(c.name, {
            status: false,
            wsPort: '未知',
            camera: c
        }))
    },
    _onEvent: (state: IStreamControlState, eventName: string) => {
        state.dialog.visible = true
        state.dialog.title = eventName
        state.form.path = useLocalStorage().getLocalStorage('bishe-rootFilePath')
    },
    _onConfirm: async (state: IStreamControlState, { name, user, camera }) => {
        let notif = {
            opts: {},
            instance: null,
        }
        let ajax = {
            name: '',
            record: recordRTSPStream,
            snapshot: snapshotRTSPStream,
            data: { ...state.form },
        }
        if (state.dialog.title === '录制') {
            ajax.name = 'record';
            ajax.data['duration'] = state.recordDialog.slider.duration;
            notif.opts['title'] = `${ajax.data.name}开始录制`;
            notif.opts['message'] = `录制时长${state.recordDialog.slider.duration}秒`
        } else if (state.dialog.title === '截图') {
            ajax.name = 'snapshot';
            ajax.data['duration'] && delete ajax.data['duration'];
            notif.opts['title'] = `${ajax.data.name}正在截图`;
            notif.opts['message'] = `截图进行中，请耐心等待...`
        }

        const setTime = ((ajax.data['duration'] && ajax.data['duration'] > 3) ? ajax.data['duration'] : 3) * 1000;
        notif.opts['duration'] = setTime;
        notif.instance = ElNotification.info(notif.opts);
        ajax.data['cameraName'] = name;
        ajax.data['uploader'] = user;
        ajax.data['camera'] = camera;
        ajax.name && ajax[ajax.name](ajax.data)
            .then((res: any) => {
                setTimeout(() => {
                    ElMessage.success(`${state.dialog.title}成功!`)
                }, setTime);
            });
        state.dialog.visible = false
    },
    _onCancel: (state: IStreamControlState) => { },
    _onInitForm: (state: IStreamControlState) => {
        state.form.name = ''
        state.form.path = ''
        state.form.type = ''
        state.form['duration'] && delete state.form['duration'];
        state.dialog.visible = false
    },
    _onStart: (state: IStreamControlState, c: ICamera) => {
        const { encrypt } = useCrypto();
        const copy = { ...c };
        copy.password = encrypt(c.password);
        copy.host = encrypt(c.host);
        copy.username = encrypt(c.username);
        if (!state.streamState.has(c.name) || !state.streamState.get(c.name).status) {
            startRTSPStream(copy).then((res: any) => {
                ElMessage[res.type](res.message);
                if (res.type === 'success') {
                    const copyObj = { ...state.streamState.get(c.name) };
                    copyObj.status = true;
                    copyObj.wsPort = res.stream.wsPort;
                    state.streamState.set(c.name, copyObj)
                }
            })
        } else {
            stopRTSPStream({ name: c.name }).then((res: any) => {
                ElMessage.success(`${c.name}停止推流`)
                const copyObj = { ...state.streamState.get(c.name) };
                copyObj.status = false;
                copyObj.wsPort = null;
                state.streamState.set(c.name, copyObj)
            }).catch((err: any) => {
                ElMessage.error(`${c.name}停止推流失败`)
            })
        }
    }
}
const getters: IStreamControlGetter = {

}

export const streamControl: Module<IStreamControlState, RootState> = {
    namespaced: true,
    state,
    actions,
    mutations,
    getters,
}
